/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   Module Name          : com.yaodian100.mall.search.web.SearchAction
   Module Description   :

   Date Created      : 2010/1/27
   Original Author   : jeff.ma
   Team              : yaodian100
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   MODIFICATION HISTORY
   ------------------------------------------------------------------------------
   Date Modified       Modified by       Comments
   ------------------------------------------------------------------------------
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
package com.yaodian100.mall.search.web;

import java.io.UnsupportedEncodingException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;
import com.yaodian100.core.common.dao.impl.CommonCriteria;
import com.yaodian100.core.common.entity.SimplePager;
import com.yaodian100.core.common.service.BaseManager;
import com.yaodian100.core.common.utils.DateUtil;
import com.yaodian100.core.common.utils.JspUtil;
import com.yaodian100.core.common.utils.StringUtils;
import com.yaodian100.core.logger.service.LogService;
import com.yaodian100.ec.category.entity.Category;
import com.yaodian100.ec.category.service.CategoryService;
import com.yaodian100.ec.product.entity.Brand;
import com.yaodian100.ec.product.service.ProductService;
import com.yaodian100.ec.search.HotTermSumInfo;
import com.yaodian100.ec.search.SearchManager;
import com.yaodian100.ec.search.SearchResult;
import com.yaodian100.ec.search.entity.SearchHistory;
import com.yaodian100.ec.search.entity.SearchHistoryItem;
import com.yaodian100.mall.member.util.UserData;

/**
 * @author jeff.ma
 * 
 */
public class SearchAction extends ActionSupport implements Preparable {

	@Resource
	private SearchManager searchManager;
	@Resource
	private BaseManager baseMgr;

	private ProductService productService;
	private Brand brand;

	public class CategoryCompare implements Comparator<Category> {

		/** default constructor */
		public CategoryCompare() {
			super();
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
		 */
		@Override
		public int compare(Category o1, Category o2) {
			if (o1 != null && o2 != null) {
				return (o1.getShowSeq() - o2.getShowSeq());
			} else {
				return -1;
			}
		}
	}

	@Autowired
	private LogService logService;

	/** serialVersionUID */
	private static final long serialVersionUID = 6078210882620612906L;

	public static final String IMAGE = "image";
	private final Logger logger = LoggerFactory.getLogger(SearchAction.class);
	@Autowired
	private CategoryService categoryService;

	private int pageSize = 40;
	private String searchKeyword;
	private String minPrice;
	private String maxPrice;
	private String startDate;
	private String endDate;
	private String sortOrderType;
	private String searchWithBrief;
	private String searchWithDescription;
	private String cleanHistory;
	private String fuzzySearch;
	private String prefix;
	private String q;
	private String z;
	private Object[] categoryL3s;
	private String totalPage;
	private Category category;
	private String partner;
	private String brandId;

	/**
	 * @return the brandId
	 */
	public String getBrandId() {
		return brandId;
	}

	/**
	 * @param brandId the brandId to set
	 */
	public void setBrandId(String brandId) {
		this.brandId = brandId;
	}

	/**
	 * @return the category
	 */
	public Category getCategory() {
		return category;
	}

	/**
	 * @param category the category to set
	 */
	public void setCategory(Category category) {
		this.category = category;
	}

	/**
	 * @return the z
	 */
	public String getZ() {
		return z;
	}

	/**
	 * @param z the z to set
	 */
	public void setZ(String z) {
		this.z = z;
	}

	/**
	 * @return the totalPage
	 */
	public String getTotalPage() {
		return totalPage;
	}

	/**
	 * @param totalPage the totalPage to set
	 */
	public void setTotalPage(String totalPage) {
		this.totalPage = totalPage;
	}

	/**
	 * @return the categoryL3s
	 */
	public Object[] getCategoryL3s() {
		return categoryL3s;
	}

	/**
	 * @param categoryL3s the categoryL3s to set
	 */
	public void setCategoryL3s(Object[] categoryL3s) {
		this.categoryL3s = categoryL3s;
	}

	/**
	 * @return the q
	 */
	public String getQ() {
		return q;
	}

	/**
	 * @param q the q to set
	 */
	public void setQ(String q) {
		this.q = q;
	}

	private List<HotTermSumInfo> autoCompleteTerms;

	/**
	 * @return the autoCompleteTerms
	 */
	public List<HotTermSumInfo> getAutoCompleteTerms() {
		return autoCompleteTerms;
	}

	/**
	 * @param autoCompleteTerms the autoCompleteTerms to set
	 */
	public void setAutoCompleteTerms(List<HotTermSumInfo> autoCompleteTerms) {
		this.autoCompleteTerms = autoCompleteTerms;
	}

	/**
	 * @return the prefix
	 */
	public String getPrefix() {
		return prefix;
	}

	/**
	 * @param prefix the prefix to set
	 */
	public void setPrefix(String prefix) {
		this.prefix = prefix;
	}

	/**
	 * @return the fuzzySearch
	 */
	public String getFuzzySearch() {
		return fuzzySearch;
	}

	/**
	 * @param fuzzySearch the fuzzySearch to set
	 */
	public void setFuzzySearch(String fuzzySearch) {
		this.fuzzySearch = fuzzySearch;
	}

	/**
	 * @return the cleanHistory
	 */
	public String getCleanHistory() {
		return cleanHistory;
	}

	/**
	 * @param cleanHistory the cleanHistory to set
	 */
	public void setCleanHistory(String cleanHistory) {
		this.cleanHistory = cleanHistory;
	}

	/**
	 * @return the searchWithBrief
	 */
	public String getSearchWithBrief() {
		return searchWithBrief;
	}

	/**
	 * @param searchWithBrief the searchWithBrief to set
	 */
	public void setSearchWithBrief(String searchWithBrief) {
		this.searchWithBrief = searchWithBrief;
	}

	/**
	 * @return the searchWithDescription
	 */
	public String getSearchWithDescription() {
		return searchWithDescription;
	}

	/**
	 * @param searchWithDescription the searchWithDescription to set
	 */
	public void setSearchWithDescription(String searchWithDescription) {
		this.searchWithDescription = searchWithDescription;
	}

	/**
	 * @return the sortOrderType
	 */
	public String getSortOrderType() {
		return sortOrderType;
	}

	/**
	 * @param sortOrderType the sortOrderType to set
	 */
	public void setSortOrderType(String sortOrderType) {
		this.sortOrderType = sortOrderType;
	}

	/**
	 * @return the startDate
	 */
	public String getStartDate() {
		return startDate;
	}

	/**
	 * @param startDate the startDate to set
	 */
	public void setStartDate(String startDate) {
		this.startDate = startDate;
	}

	/**
	 * @return the endDate
	 */
	public String getEndDate() {
		return endDate;
	}

	/**
	 * @param endDate the endDate to set
	 */
	public void setEndDate(String endDate) {
		this.endDate = endDate;
	}

	private List<String> adv;
	private String type = "text";

	private String display = "image"; // list or image
	private SimplePager pager;

	/**
	 * @param pager the pager to set
	 */
	public void setPager(SimplePager pager) {
		this.pager = pager;
	}

	private List<Category> categories;

	private List<Category> categoryL1List;

	private String pathname;
	private String flag1;
	private String flag2;
	private String flag3;
	private String flag4;
	private String flag5;
	private String flag6;
	private String flag7;

	/**
	 * @return the flag6
	 */
	public String getFlag6() {
		return flag6;
	}

	/**
	 * @param flag6 the flag6 to set
	 */
	public void setFlag6(String flag6) {
		this.flag6 = flag6;
	}

	/**
	 * @return the flag7
	 */
	public String getFlag7() {
		return flag7;
	}

	/**
	 * @param flag7 the flag7 to set
	 */
	public void setFlag7(String flag7) {
		this.flag7 = flag7;
	}

	public String categoryL3() {
		DetachedCriteria dc = DetachedCriteria.forClass(Category.class);
		Date now = new Date();
		if (z != null && z.length() > 0) {
			dc.add(Restrictions.eq("parentId", Long.valueOf(z)));
			dc.add(Restrictions.eq("level", "2"));
			dc.add(Restrictions.le("startDate", now));
			dc.add(Restrictions.ge("endDate", now));
			dc.add(Restrictions.eq("isVisible", "Y"));
			categoryL3s = baseMgr.findByCriteria(dc);
		}
		return "categoryL3";
	}

	public String advInput() {
		CommonCriteria cri = new CommonCriteria();
		Date now = DateUtil.getCurrentTime();
		cri.addIn("level", Arrays.asList("0", "1"));
		cri.addLe("startDate", now);
		cri.addGe("endDate", now);
		cri.addEq("isVisible", "Y");
		type = "input";
		categories = categoryService.getList(0, -1, cri, new String[] { "id asc" });
		adv = Arrays.asList("brief", "description");
		return INPUT;
	}

	/**
	 * @return the adv
	 */
	public List<String> getAdv() {
		if (adv == null) {
			adv = Arrays.asList("");
		}
		return adv;
	}

	/**
	 * @return the categories
	 */
	public List<Category> getCategories() {
		return categories;
	}

	/**
	 * @return the categoryL1List
	 */
	public List<Category> getCategoryL1List() {
		if (categoryL1List == null && categories != null) {
			categoryL1List = new ArrayList();
			for (Category c : categories) {
				if ("0".equals(c.getLevel())) {
					categoryL1List.add(c);
				}
			}
			Comparator<Category> comp = new CategoryCompare();
			Collections.sort(categoryL1List, comp);
		}
		return categoryL1List;
	}

	/**
	 * @return the display
	 */
	public String getDisplay() {
		return display;
	}

	public String getFlag1() {
		return flag1;
	}

	public String getFlag2() {
		return flag2;
	}

	public String getFlag3() {
		return flag3;
	}

	public String getFlag4() {
		return flag4;
	}

	public String getFlag5() {
		return flag5;
	}

	/**
	 * @return the maxPrice
	 */
	public String getMaxPrice() {
		return maxPrice;
	}

	/**
	 * @return the minPrice
	 */
	public String getMinPrice() {
		return minPrice;
	}

	/**
	 * @return the pager
	 */
	public SimplePager getPager() {
		return pager;
	}

	public String getPathname() {
		return pathname;
	}

	/**
	 * @return the searchKey
	 */
	public String getSearchKeyword() {
		return searchKeyword;
	}

	/**
	 * @return the type
	 */
	public String getType() {
		return type;
	}

	private String pIndex;
	private SearchResult result1;

	/**
	 * @return the result1
	 */
	public SearchResult getResult1() {
		return result1;
	}

	/**
	 * @param result1 the result1 to set
	 */
	public void setResult1(SearchResult result1) {
		this.result1 = result1;
	}

	/**
	 * @return the pIndex
	 */
	public String getpIndex() {
		return pIndex;
	}

	/**
	 * @param pIndex the pIndex to set
	 */
	public void setpIndex(String pIndex) {
		this.pIndex = pIndex;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.opensymphony.xwork2.Preparable#prepare()
	 */
	@Override
	public void prepare() throws Exception {
		clearErrorsAndMessages();
		if (pager == null) {
			pager = new SimplePager(2);
		}
	}

	public String subCategory() {
		try {
			HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(
					ServletActionContext.HTTP_REQUEST);

			HttpServletResponse response = (HttpServletResponse) ActionContext.getContext().get(
					ServletActionContext.HTTP_RESPONSE);
			UserData userData = new UserData(request, response);
			String serverName = request.getServerName();

			String applySource = userData.getApplySource();
			String catId = "";
			if (z != null && !z.equals("0")) {
				catId = z;
			}
			Category category = getCategory(z);
			String querytype = "";
			String level = category.getLevel();
			String categoryPath = category.getCategoryPath();

			String blocksyntax = searchManager.blockSyntax_V2(z, searchKeyword, serverName, applySource, searchWithBrief,
					searchWithDescription, level, categoryPath, flag2, flag3, flag4, flag5, flag6, flag7, minPrice, maxPrice,
					startDate, endDate, flag1, partner, brandId);
			String queryoption = "";
			if (fuzzySearch != null && fuzzySearch.equals("1")) {
				queryoption = "\"FuzzySearch\"";
			}
			String countquery = "";
			String displayfields = "";
			String weightsyntax = "";
			int categoryLevel = -1;
			int theCatL = Integer.valueOf(category.getLevel());
			if (theCatL > 2) {
				categoryLevel = 2;
			} else {
				categoryLevel = theCatL;
			}

			String searchKeywordU = JspUtil.urlDecoding(searchKeyword, "UTF-8");

			result1 = searchManager.query(categoryLevel, catId, searchKeywordU, querytype, 0, 1, blocksyntax, "",
					queryoption, countquery, displayfields, weightsyntax, false);
			request.setAttribute("subCategories", result1.categories);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		return "subCategory";
	}

	public static void main(String args[]) {
		SearchAction sa = new SearchAction();
		// sa.setSearchKeyword("鞋子");
		// sa.setZ("1727");
		String z = "0";
		// sa.setFlag2("1");
		// sa.setFlag3("1");
		// sa.setFlag4("1");
		// sa.setFlag5("1");
		// sa.setFlag6("1");
		// sa.setFlag7("1");

		// sa.setMinPrice("50");
		// sa.setMaxPrice("500");
		// sa.setStartDate("2010-10-11");
		// sa.setEndDate("2010-10-8");
		// sa.setFlag1("1");
		// sa.setSearchWithBrief("1");
		// sa.setSearchWithDescription("1");
		// sa.setPartner("DAPHNE");
		sa.forTest = true;
		// System.out.println(sa.getBlockSyntax());

		System.out.println("result:" + sa.getBlockSyntax_V2(z));
	}

	public boolean forTest = false;

	public Category getCategory(String categoryId) {
		if (categoryId == null || categoryId.length() == 0) {
			return null;
		}
		if (forTest) {
			Category category = new Category();
			category.setLevel("1");
			category.setCategoryPath("1770");
			return category;
		} else {
			return (Category) baseMgr.get(Category.class, Long.valueOf(categoryId));
		}
	}

	private int irootAt = 0;

	private int getRootAt() {
		irootAt++;
		if (irootAt > 2) {
			irootAt = 1;
		}
		return irootAt;
	}

	// public String getBlockSyntax() {
	// return blockSyntax();
	// }

	public String getBlockSyntax_V2(String z) {
		HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST);

		HttpServletResponse response = (HttpServletResponse) ActionContext.getContext().get(
				ServletActionContext.HTTP_RESPONSE);
		UserData userData = new UserData(request, response);
		String serverName = request.getServerName();

		String applySource = userData.getApplySource();
		Category category = getCategory(z);
		String level = category.getLevel();
		String categoryPath = category.getCategoryPath();

		String blocksyntax = searchManager.blockSyntax_V2(z, searchKeyword, serverName, applySource, searchWithBrief,
				searchWithDescription, level, categoryPath, flag2, flag3, flag4, flag5, flag6, flag7, minPrice, maxPrice,
				startDate, endDate, flag1, partner, brandId);
		return blocksyntax;
	}

	//
	// private String blockSyntax_V2(String z) {
	// if (z != null && z.equals("0")) {
	// z = null;
	// }
	// Category category = null;
	// if (z != null && z.length() > 0) {
	// category = getCategory(z);
	// }
	// HttpServletRequest request = null;
	// HttpServletResponse response = null;
	// UserData userData = null;
	// String serverName = null;
	// String applySource = null;
	// try {
	// request = (HttpServletRequest) ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST);
	// response = (HttpServletResponse) ActionContext.getContext().get(ServletActionContext.HTTP_RESPONSE);
	// userData = new UserData(request, response);
	// serverName = request.getServerName();
	// serverName = StringUtils.replace(serverName, ".", "-");
	// applySource = userData.getApplySource();
	// } catch (Exception e) {
	// // e.printStackTrace();
	// }
	// String searchKeywordU = null;
	// String searchWith = "";
	// String syntax = "";
	// String categoryOnly = "";
	// List<String> andSyntaxList = new ArrayList<String>();
	// if (searchKeyword != null && !searchKeyword.equals("")) {
	// searchKeywordU = JspUtil.urlDecoding(searchKeyword, "UTF-8");
	//
	// if (searchWithBrief != null && searchWithBrief.equals("1")
	// && (searchWithDescription == null || !searchWithDescription.equals("1"))) {
	// searchWith = "{'QC1':{'QT':0,'Operand1':'"
	// + searchKeywordU
	// + "','QueryFieldNames':"
	// +
	// "['PRODUCT_NAME','PROMOTE_NAME','MAIN_CATEGORY_NAME','PRODUCT_KEYWORD','PRODUCT_BRIEF','PRODUCT_ID','PRODUCT_BRAND','PRODUCT_BRAND_ENAME','BRAND_SYNONYM','CATEGORY_L1_NAME','CATEGORY_L2_NAME','CATEGORY_L3_NAME', 'CATEGORY_LX_NAME']}}";
	// } else if (searchWithBrief != null && searchWithBrief.equals("1") && searchWithDescription != null
	// && searchWithDescription.equals("1")) {
	// searchWith = "{'QC1':{'QT':0,'Operand1':'"
	// + searchKeywordU
	// + "','QueryFieldNames':"
	// +
	// "['PRODUCT_NAME','PROMOTE_NAME','MAIN_CATEGORY_NAME','PRODUCT_KEYWORD','PRODUCT_BRIEF','PRODUCT_ID','PRODUCT_BRAND','PRODUCT_BRAND_ENAME','BRAND_SYNONYM','CATEGORY_L1_NAME','CATEGORY_L2_NAME','CATEGORY_L3_NAME', 'CATEGORY_LX_NAME','PRODUCT_DESCRIPTION']}}";
	// } else if ((searchWithBrief == null || !searchWithBrief.equals("1"))
	// && (searchWithDescription != null && searchWithDescription.equals("1"))) {
	// searchWith = "{'QC1':{'QT':0,'Operand1':'"
	// + searchKeywordU
	// + "','QueryFieldNames':"
	// +
	// "['PRODUCT_NAME','PROMOTE_NAME','MAIN_CATEGORY_NAME','PRODUCT_KEYWORD','PRODUCT_ID','PRODUCT_BRAND','PRODUCT_BRAND_ENAME','BRAND_SYNONYM','CATEGORY_L1_NAME','CATEGORY_L2_NAME','CATEGORY_L3_NAME', 'CATEGORY_LX_NAME','PRODUCT_DESCRIPTION']}}";
	// } else {
	// searchWith = "{'QC1':{'QT':0,'Operand1':'"
	// + searchKeywordU
	// + "','QueryFieldNames':"
	// +
	// "['PRODUCT_NAME','PROMOTE_NAME','MAIN_CATEGORY_NAME','PRODUCT_KEYWORD','PRODUCT_ID','PRODUCT_BRAND','PRODUCT_BRAND_ENAME','BRAND_SYNONYM','CATEGORY_L1_NAME','CATEGORY_L2_NAME','CATEGORY_L3_NAME', 'CATEGORY_LX_NAME']}}";
	// }
	// andSyntaxList.add(searchWith);
	// }
	// {
	// // 只搜目录
	// if (z != null && z.length() > 0) {
	//
	// String theCategoryL = z;
	// String categoryLName = "";
	// if (category.getLevel().equals("2")) {
	// categoryLName = "CATEGORY_L3";
	// } else if (category.getLevel().equals("1")) {
	// categoryLName = "CATEGORY_L2";
	// } else if (category.getLevel().equals("0")) {
	// categoryLName = "CATEGORY_L1";
	// } else {
	// categoryLName = "CATEGORY_LX";
	// String[] categoryIds = category.getCategoryPath().split("/");
	// if (categoryIds.length > 3) {
	// theCategoryL = categoryIds[categoryIds.length - 1];
	// }
	// }
	// categoryOnly = "{'QC1':{'QT':0,'Operand1':'" + theCategoryL + "','QueryFieldNames':['" + categoryLName + "']}}";
	// andSyntaxList.add(categoryOnly);
	// }
	//
	// }
	//
	// /**
	// *
	// * comboFlag
	// *
	// */
	// List<String> comboFlags = new ArrayList<String>();
	// // 立減
	// String discountSStr = "";
	// if (flag2 != null && flag2.equals("1")) {
	// if (applySource == null) {
	// applySource = "";
	// }
	// // scope0
	// String d1 = "'QC1':{'QT':0,'Operand1':'" + serverName + "_" + applySource
	// + "','QueryFieldNames':['SCOPE0_PR_DC']}";
	// // scope1
	// String d2 = "'QCompC2':{'QC1':{'QT':0,'Operand1':'" + serverName + "_" + applySource
	// + "','QueryFieldNames':['SCOPE1_PR_DC']}";
	// if (z != null && z.length() > 0) {
	// d2 += ",'QCOP':1,'QC2':{'QT':0,'Operand1':'" + z + "','QueryFieldNames':['SCOPE1_PR_C']}}";
	// } else {
	// d2 += "}";
	// }
	// // scope2
	// String d3 = "'QC2':{'QT':0,'Operand1':'" + serverName + "_" + applySource
	// + "','QueryFieldNames':['SCOPE2_PR_DC']}";
	// discountSStr = "{'QCompC1':{" + d1 + ",'QCOP':2," + d2 + "},'QCOP':2," + d3 + "}";
	// comboFlags.add(discountSStr);
	// }
	// // 立折
	//
	// String percentSStr = "";
	// if (flag3 != null && flag3.equals("1")) {
	// if (applySource == null) {
	// applySource = "";
	// }
	// // scope0
	// String d1 = "'QC1':{'QT':0,'Operand1':'" + serverName + "_" + applySource
	// + "','QueryFieldNames':['SCOPE0_PO_DC']}";
	// // scope1
	// String d2 = "'QCompC2':{'QC1':{'QT':0,'Operand1':'" + serverName + "_" + applySource
	// + "','QueryFieldNames':['SCOPE1_PO_DC']}";
	// if (z != null && z.length() > 0) {
	// d2 += ",'QCOP':1,'QC2':{'QT':0,'Operand1':'" + z + "','QueryFieldNames':['SCOPE1_PO_C']}}";
	// } else {
	// d2 += "}";
	// }
	// // scope2
	// String d3 = "'QC2':{'QT':0,'Operand1':'" + serverName + "_" + applySource
	// + "','QueryFieldNames':['SCOPE2_PO_DC']}";
	//
	// percentSStr = "{'QCompC1':{" + d1 + ",'QCOP':2," + d2 + "},'QCOP':2," + d3 + "}";
	// comboFlags.add(percentSStr);
	// }
	// // 贈品
	// String presentSStr = "";
	// if (flag4 != null && flag4.equals("1")) {
	// presentSStr = "{'QC1':{'QT':2,'Operand1':'1','BOP':2,'MetaField':'CAM_PRESENT'}}";
	// comboFlags.add(presentSStr);
	// }
	// // 購物金
	// String couponSStr = "";
	// if (flag5 != null && flag5.equals("1")) {
	// couponSStr = "{'QC1':{'QT':2,'Operand1':'1','BOP':2,'MetaField':'CAM_BONUS'}}";
	// comboFlags.add(couponSStr);
	// }
	// // n選m
	// String nmSStr = "";
	// if (flag6 != null && flag6.equals("1")) {
	// nmSStr = "{'QC1':{'QT':2,'Operand1':'1','BOP':2,'MetaField':'CAM_NNM'}}";
	// comboFlags.add(nmSStr);
	// }
	// // 加購
	// String addonSStr = "";
	// if (flag7 != null && flag7.equals("1")) {
	// addonSStr = "{'QC1':{'QT':2,'Operand1':'1','BOP':2,'MetaField':'CAM_ADDON'}}";
	// comboFlags.add(addonSStr);
	// }
	// String comboSyntax = "";
	// for (String flag : comboFlags) {
	// // System.out.println("flag:" + flag);
	// if (!comboSyntax.equals("")) {
	// comboSyntax = "{'QCompC1':" + comboSyntax + ",'QCOP':2,'QCompC2':" + flag + "}";
	// } else {
	// comboSyntax = flag;
	// }
	// }
	// if (!comboSyntax.equals("")) {
	// andSyntaxList.add(comboSyntax);
	// }
	//
	// // 上架价
	// String shelfPriceStr = "";
	// if (minPrice != null && minPrice.length() > 0 && !minPrice.equals("null")
	// && (maxPrice == null || maxPrice.length() == 0)) {
	// shelfPriceStr = "{'QC1':{'QT':2,'Operand1':" + minPrice + ",'BOP':3,'MetaField':'SHELF_PRICE'}}";
	//
	// } else if (minPrice != null && minPrice.length() > 0 && !minPrice.equals("null") && maxPrice != null
	// && maxPrice.length() > 0 && !maxPrice.equals("null")) {
	// try {
	// int minPricei = Integer.valueOf(minPrice);
	// int maxPricei = Integer.valueOf(maxPrice);
	// if (minPricei > maxPricei) {
	// String tempMinPrice = maxPrice;
	// String tempMaxPrice = minPrice;
	// minPrice = tempMinPrice;
	// maxPrice = tempMaxPrice;
	// }
	// } catch (Exception e) {
	// // DO NOTHING
	// }
	// shelfPriceStr = "{'QC1':{'QT':2,'Operand1':" + minPrice + ",'BOP':1, 'Operand2':" + maxPrice
	// + ",'MetaField':'SHELF_PRICE'}}";
	//
	// } else if (maxPrice != null && maxPrice.length() > 0 && !maxPrice.equals("null")
	// && (maxPrice == null || maxPrice.length() == 0)) {
	// shelfPriceStr = "{'QC1':{'QT':2,'Operand1':" + maxPrice + ",'BOP':6,'MetaField':'SHELF_PRICE'}}";
	// }
	// if (!shelfPriceStr.equals("")) {
	// andSyntaxList.add(shelfPriceStr);
	// }
	// // 上架日期
	// String shelfDt = "";
	// if (startDate != null && startDate.length() > 0 && !startDate.equals("null")
	// && (endDate == null || endDate.length() == 0)) {
	// shelfDt = "{'QCompC1':{'QC1':{'QT':2,'Operand1':'" + startDate
	// + "','BOP':6,'MetaField':'SHELF_START_DATE'}, 'QCOP':1,'QC2':{'QT':2,'Operand1':'" + startDate
	// + "','BOP':3,'MetaField':'SHELF_END_DATE'}}}";
	//
	// } else if (startDate != null && startDate.length() > 0 && !startDate.equals("null") && endDate != null
	// && endDate.length() > 0 && !endDate.equals("null")) {
	// try {
	// int startDatei = Integer.valueOf(startDate.replaceAll("-", ""));
	// int endDatei = Integer.valueOf(endDate.replaceAll("-", ""));
	// if (startDatei > endDatei) {
	// String tempStartDate = endDate;
	// String tempEndDate = startDate;
	// startDate = tempStartDate;
	// endDate = tempEndDate;
	// }
	// } catch (Exception e) {
	// // DO NOTHING
	// }
	//
	// shelfDt = "{'QCompC1':{'QC1':{'QT':2,'Operand1':'" + startDate
	// + "','BOP':6,'MetaField':'SHELF_START_DATE'},'QCOP':1,'QC2':{'QT':2,'Operand1':'" + startDate
	// + "','BOP':3,'MetaField':'SHELF_END_DATE'}},'QCOP':1,'QCompC2':{'QC1':{'QT':2,'Operand1':'" + endDate
	// + "','BOP':3,'MetaField':'SHELF_END_DATE'},'QCOP':1,'QC2':{'QT':2,'Operand1':'" + endDate
	// + "','BOP':6,'MetaField':'SHELF_START_DATE'}}}";
	// } else if (endDate != null && endDate.length() > 0 && !endDate.equals("null")
	// && (startDate == null || startDate.length() == 0)) {
	// shelfDt = "{'QCompC1':{'QC1':{'QT':2,'Operand1':'" + endDate
	// + "','BOP':3,'MetaField':'SHELF_END_DATE'},'QCOP':1,'QC2':{'QT':2,'Operand1':'" + endDate
	// + "','BOP':6,'MetaField':'SHELF_START_DATE'}}}";
	// }
	// if (!shelfDt.equals("")) {
	// andSyntaxList.add(shelfDt);
	// }
	// // 預購
	// String notPreBuyStr = "";
	// if (flag1 != null && flag1.equals("1")) {
	// notPreBuyStr = "{'QC1':{'QT':2,'Operand1':'0','BOP':2,'MetaField':'PRODUCT_TYPE'}"
	// + ",'QCOP':2,'QC2':{'QT':2,'Operand1':'6','BOP':2,'MetaField':'PRODUCT_TYPE'}}";
	// andSyntaxList.add(notPreBuyStr);
	// }
	//
	// // 达芙妮到店取货
	// String partnerStr = "";
	// if (partner != null && partner.equals("DAPHNE")) {
	// partnerStr = "{'QC1':{'QT':0, 'Operand1':'DAPHNE','QueryFieldNames':['FOR_PARTNER']}}";
	// andSyntaxList.add(partnerStr);
	// }
	// // brand id
	// String brandStr = "";
	// if (brandId != null && brandId.length() > 0) {
	// brandStr = "{'QC1':{'QT':2,'Operand1':'" + brandId + "','BOP':2,'MetaField':'BRAND_ID'}}";
	// andSyntaxList.add(brandStr);
	// }
	// for (String and : andSyntaxList) {
	// // System.out.println("and:" + and);
	// if (!syntax.equals("")) {
	// syntax = "{'QCompC1':" + syntax + ",'QCOP':1,'QCompC2':" + and + "}";
	// } else {
	// syntax = and;
	// }
	// }
	//
	// return syntax;
	// }

	// private String orderSyntax() {
	// String sotStr = "{'OrderByMetaField':'_weight_ desc,SOLD_COUNT desc,CLICK desc','OrderDirection':1}";
	// if (searchKeyword == null || searchKeyword.length() == 0) {
	// sortOrderType = "6";
	// }
	// if (sortOrderType != null && sortOrderType.length() > 0) {
	// int sot = Integer.valueOf(sortOrderType);
	// switch (sot) {
	// case 0: {
	// sotStr = "{'OrderByMetaField':'SHELF_START_DATE desc,SOLD_COUNT desc,CLICK desc','OrderDirection':1}";
	// break;
	// }
	// case 1: {
	// sotStr = "{'OrderByMetaField':'SHELF_START_DATE asc,SOLD_COUNT desc,CLICK desc','OrderDirection':0}";
	// break;
	// }
	// case 2: {
	// sotStr = "{'OrderByMetaField':'SHELF_PRICE asc,SOLD_COUNT desc,CLICK desc','OrderDirection':0}";
	// break;
	// }
	// case 3: {
	// sotStr = "{'OrderByMetaField':'SHELF_PRICE desc,SOLD_COUNT desc,CLICK desc','OrderDirection':1}";
	// break;
	// }
	// case 4: {
	// sotStr = "{'OrderByMetaField':'SOLD_COUNT desc,CLICK desc','OrderDirection':1}";
	// break;
	// }
	// case 5: {
	// sotStr = "{'OrderByMetaField':'SOLD_COUNT asc,CLICK desc','OrderDirection':0}";
	// break;
	// }
	// case 6: {
	// // 相關度＝不選任何條件
	// sotStr = "{'OrderByMetaField':'_weight_ desc,SOLD_COUNT desc,CLICK desc','OrderDirection':1}";
	// break;
	// }
	// }
	// }
	// return sotStr;
	// }

	public String cleanHistory() {
		String page = "success";

		HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST);
		HttpServletResponse response = (HttpServletResponse) ActionContext.getContext().get(
				ServletActionContext.HTTP_RESPONSE);
		UserData userData = new UserData(request, response);
		String shId = userData.readRawValue("shId");
		String memberId = StringUtils.defaultString(userData.getMemberId());
		if (memberId != null && memberId.length() > 0) {
			shId = memberId;
		}
		page = lSearch();
		if (shId != null) {
			SearchHistory sh = (SearchHistory) baseMgr.get(SearchHistory.class, shId);
			baseMgr.delete(sh);
		}

		return page;
	}

	private String lSearch() {
		if (z != null && z.equals("0")) {
			z = null;
		}
		try {
			Category category = null;
			if (z != null && !z.equals("0") && z.length() > 0) {
				category = getCategory(z);
				this.category = category;
			}
			if (pageSize > 100) {
				pageSize = 100;
			}
			HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(
					ServletActionContext.HTTP_REQUEST);
			if (pager == null) {
				pIndex = "0";
			} else {
				int totalPagei = 0;
				try {
					totalPagei = Integer.valueOf(totalPage);

				} catch (Exception e) {

				}
				if (pager.getCurrentPage() >= totalPagei) {
					pIndex = String.valueOf(totalPagei - 1);
				} else {
					pIndex = String.valueOf(pager.getCurrentPage());
				}
			}
			String catId = z;
			if (catId != null && catId.equals("0")) {
				catId = "";
			}
			String querytype = "";
			int pagesize = pageSize;

			String orderby = searchManager.orderSyntax(searchKeyword, sortOrderType);
			String queryoption = "";
			if (fuzzySearch != null && fuzzySearch.equals("1")) {
				queryoption = "'FuzzySearch'";
			}
			String countquery = "";
			String displayfields = "";
			String weightsyntax = "";
			int categoryLevel = -1;

			/*
			 * if (searchKeyword == null || searchKeyword.length() == 0) { // categoryLevel = -1; catId = ""; }
			 */
			if (category != null) {
				categoryLevel = Integer.valueOf(category.getLevel());
				// if (category.getLevel().equals("0")) {
				// categoryLevel = 0;
				// } else if (category.getLevel().equals("1")) {
				// categoryLevel = 1;
				// } else {
				// categoryLevel = 2;
				// }
			}
			HttpServletResponse response = (HttpServletResponse) ActionContext.getContext().get(
					ServletActionContext.HTTP_RESPONSE);
			UserData userData = new UserData(request, response);
			String serverName = request.getServerName();

			String applySource = userData.getApplySource();
			String level = String.valueOf(categoryLevel);
			if (categoryLevel == -1) {
				level = "0";
			}
			String categoryPath = "";
			if (category != null) {
				categoryPath = category.getCategoryPath();
			}

			String blocksyntax = searchManager.blockSyntax_V2(z, searchKeyword, serverName, applySource, searchWithBrief,
					searchWithDescription, level, categoryPath, flag2, flag3, flag4, flag5, flag6, flag7, minPrice, maxPrice,
					startDate, endDate, flag1, partner, brandId);
			String parentCatId = "";
			if (category != null) {
				String[] categoryIds = category.getCategoryPath().split("/");
				// if (categoryIds.length > 2) {
				// parentCatId = categoryIds[categoryIds.length - 2];
				if (categoryLevel > 0) {
					parentCatId = categoryIds[categoryLevel - 1];
				} else {
					parentCatId = "";
				}
				// } else {
				// parentCatId = "";
				// }
			}

			String searchKeywordU = JspUtil.urlDecoding(searchKeyword, "UTF-8");
			if (categoryLevel != -1 || (brandId != null && brandId.length() > 0)
					|| (searchKeyword != null && searchKeyword.length() > 0)) {
				int theCl = -1;
				if (categoryLevel != -1) {
					theCl = categoryLevel - 1;
				}

				Category parentCategory = getCategory(parentCatId);
				String parentLevel = "0";
				String parentCategoryPath = "";
				if (parentCategory != null) {
					parentCategory.getLevel();
					parentCategory.getCategoryPath();
				}

				String blockSyntax_0 = searchManager.blockSyntax_V2(parentCatId, searchKeyword, serverName, applySource,
						searchWithBrief, searchWithDescription, parentLevel, parentCategoryPath, flag2, flag3, flag4, flag5, flag6,
						flag7, minPrice, maxPrice, startDate, endDate, flag1, partner, brandId);
				// if (partner != null && partner.length() > 0) {
				// theCl = -1;
				// parentCatId = "";
				// }
				SearchResult result0 = searchManager.query(theCl, parentCatId, searchKeywordU, querytype, Integer
						.parseInt(pIndex), 1, blockSyntax_0, orderby, queryoption, countquery, displayfields, weightsyntax, false);
				request.setAttribute("result0", result0);

			}

			if (searchKeyword != null && searchKeyword.length() > 0 || z != null || (brandId != null && brandId.length() > 0)) {
				// if (partner != null && partner.length() > 0) {
				// categoryLevel = -1;
				// catId = "";
				// }
				result1 = searchManager.query(categoryLevel, catId, searchKeywordU, querytype, Integer.parseInt(pIndex),
						pagesize, blocksyntax, orderby, queryoption, countquery, displayfields, weightsyntax, false);

				if (getPager() == null) {
					setPager(new SimplePager(2));
				}
				getPager().setPageRecord(pagesize);
				getPager().setTotalSize(result1.getTotal());
				if (result1.getTotal() == 0) {
					// fuzzySearch count
					queryoption = "'FuzzySearch'";
					SearchResult r = searchManager.query(-1, "", searchKeywordU, "", 0, 10, "", "", queryoption, "", "", "",
							false);
					fuzzySearchCount = r.getTotal();
				}
			}
		} catch (RemoteException e) {
			e.printStackTrace();
		}

		if ("image".equals(display) || display == null || display.equals("")) {
			return IMAGE;
		} else {
			return SUCCESS;
		}
	}

	public String searchBrand() {
		String page = lSearch();
		saveSearchHistory();
		listSearchHistory();
		brand = productService.getBrandByBrandId(brandId);
		if (null != brand) {
			brand.setBrandStory(productService.readBrandFromFile(brandId));
		}
		return "brand";
	}

	public String search() throws UnsupportedEncodingException {
		String page = lSearch();
		saveSearchHistory();
		listSearchHistory();
		return page;
	}

	private int fuzzySearchCount;

	/**
	 * @return the fuzzySearchCount
	 */
	public int getFuzzySearchCount() {
		return fuzzySearchCount;
	}

	/**
	 * @param fuzzySearchCount the fuzzySearchCount to set
	 */
	public void setFuzzySearchCount(int fuzzySearchCount) {
		this.fuzzySearchCount = fuzzySearchCount;
	}

	public String listSearchHistory() {
		HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST);
		HttpServletResponse response = (HttpServletResponse) ActionContext.getContext().get(
				ServletActionContext.HTTP_RESPONSE);
		UserData userData = new UserData(request, response);
		String shId = userData.readRawValue("shId");
		String memberId = StringUtils.defaultString(userData.getMemberId());
		if (memberId != null && memberId.length() > 0) {
			shId = memberId;
		}
		if (shId != null) {
			SearchHistory sh = (SearchHistory) baseMgr.get(SearchHistory.class, shId);
			request.setAttribute("searchHistory", sh);
		}
		return "history";
	}

	private void saveSearchHistory() {

		if (searchKeyword == null || searchKeyword.length() == 0) {
			return;
		}
		String searchKeywordU = JspUtil.urlDecoding(searchKeyword, "UTF-8");
		HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST);
		HttpServletResponse response = (HttpServletResponse) ActionContext.getContext().get(
				ServletActionContext.HTTP_RESPONSE);
		UserData userData = new UserData(request, response);
		String shId = userData.readRawValue("shId");
		String memberId = StringUtils.defaultString(userData.getMemberId());
		SearchHistory sh = null;
		if (memberId != null && memberId.length() > 0) {
			shId = memberId;
		}

		if (shId == null) {
			shId = java.util.UUID.randomUUID().toString();
			userData.writeRawValue("shId", shId);
		}

		sh = (SearchHistory) baseMgr.get(SearchHistory.class, shId);
		if (sh != null) {
			boolean isExist = false;
			for (SearchHistoryItem shi : sh.getSearchItems()) {
				if (shi.getKeyword().equals(searchKeywordU)) {
					shi.setCreateDate(new Date());
					isExist = true;
					break;
				}
			}
			if (!isExist) {
				SearchHistoryItem shi = new SearchHistoryItem();
				shi.setCreateDate(new Date());
				shi.setKeyword(searchKeywordU);
				shi.setSearchHistory(sh);
				for (int i = 9; i < sh.getSearchItems().size(); i++) {

					baseMgr.delete(sh.getSearchItems().get(i));
					sh.getSearchItems().remove(i);
				}
				sh.getSearchItems().add(shi);
				baseMgr.saveOrUpdate(shi);
				// baseMgr.saveOrUpdate(sh);
			}
		} else {
			sh = new SearchHistory();
			sh.setId(shId);
			sh.setCreateDate(new Date());
			SearchHistoryItem shi = new SearchHistoryItem();
			shi.setCreateDate(new Date());
			shi.setKeyword(searchKeywordU);
			shi.setSearchHistory(sh);
			List<SearchHistoryItem> shiList = new ArrayList<SearchHistoryItem>();
			shiList.add(shi);
			sh.setSearchItems(shiList);
			baseMgr.save(sh);
		}

	}

	public String categoryChild() {
		try {
			pageSize = 1;
			search();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return "categoryChild";
	}

	public String advsearch() {

		return advInput();
	}

	public String listAutoComplete() {
		try {
			if (q != null) {
				autoCompleteTerms = searchManager.listAutoCompleteTerms(JspUtil.urlDecoding(q, "UTF-8"), 10);
			}
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		return "autoComplete";
	}

	/**
	 * @param adv the adv to set
	 */
	public void setAdv(List<String> adv) {
		this.adv = adv;
	}

	/**
	 * @param display the display to set
	 */
	public void setDisplay(String display) {
		this.display = display;
	}

	public void setFlag1(String flag1) {
		this.flag1 = flag1;
	}

	public void setFlag2(String flag2) {
		this.flag2 = flag2;
	}

	public void setFlag3(String flag3) {
		this.flag3 = flag3;
	}

	public void setFlag4(String flag4) {
		this.flag4 = flag4;
	}

	public void setFlag5(String flag5) {
		this.flag5 = flag5;
	}

	/**
	 * @param maxPrice the maxPrice to set
	 */
	public void setMaxPrice(String maxPrice) {
		this.maxPrice = maxPrice;
	}

	/**
	 * @param minPrice the minPrice to set
	 */
	public void setMinPrice(String minPrice) {
		this.minPrice = minPrice;
	}

	/**
	 * @param pageSize the pageSize to set
	 */
	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	public void setPathname(String pathname) {
		this.pathname = pathname;
	}

	/**
	 * @param searchKey the searchKey to set
	 */
	public void setSearchKeyword(String searchKey) {
		this.searchKeyword = searchKey;
	}

	/**
	 * @param type the type to set
	 */
	public void setType(String type) {
		this.type = type;
	}

	/**
	 * @return the partner
	 */
	public String getPartner() {
		return partner;
	}

	/**
	 * @param partner the partner to set
	 */
	public void setPartner(String partner) {
		this.partner = partner;
	}

	public ProductService getProductService() {
		return productService;
	}

	public void setProductService(ProductService productService) {
		this.productService = productService;
	}

	public Brand getBrand() {
		return brand;
	}

	public void setBrand(Brand brand) {
		this.brand = brand;
	}
}
